#include "tbcore/base/result.hpp"

#include <sstream>

TB_NAMESPACE_BEGIN

Result::Result() {}

Result::Result(ErrorCode code, const String& reason, int32 location) {
	if (code != kNoError || !reason.empty() || location != 0) {
		info_.reset(new ResultInfo(code, reason, location));
	}
}

Result::Result(const Result& rhs) : info_(rhs.info_) {}

Result::Result(Result&& rhs) : info_(rhs.info_) {}

Result& Result::operator=(Result&& rhs) {
  if (this != &rhs) {
    info_ = rhs.info_;
    rhs.info_.reset();
  }
  return *this;
}

Result& Result::operator=(const Result& rhs) {
	if (this != &rhs) {
		info_ = rhs.info_;
	}
	return *this;
}

Result::~Result() {}

bool Result::HasError() const {
	return (bool)info_;
}

TB::ErrorCode Result::Code() const {
	return info_ ? info_->code_ : kNoError;
}

const String& Result::Reason() const {
	static String nullReason;
	return info_ ? info_->reason_ : nullReason;
}

int32 Result::Location() const {
	return info_ ? info_->location_ : 0;
}

String Result::ToString() const {
	YSStringStream builder;

	if (info_) {
		builder << ErrorCode2String(info_->code_) <<
			_T(" occured, reason: ") << info_->reason_ << _T(", location: ");
		return builder.str();
	}
	return _T("");
}

Result::operator bool() const {
	return !HasError();
}

TB_NAMESPACE_END